/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.upo.eps.it.phama.struts.action;

import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.hibernate.HibernateException;
import org.upo.eps.it.phama.bean.Direccion;
import org.upo.eps.it.phama.bean.Cliente;
import org.upo.eps.it.phama.dao.ClienteDAO;
import org.upo.eps.it.phama.struts.actionform.ClientesActionForm;

/**
 *
 * @author grupo 4
 */
public class ClientesAction extends Action {

    /**
     * This is the action called from the Struts framework.
     *
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @throws java.lang.Exception
     * @return
     */
    @Override
    public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        /* Los métodos execute de todos los Action efectúan la misma comprobación. Si la sesión
         * guarda un atributo User es porque hay un usuario identificado, por lo que se puede
         * continuar con la ejecución del método. Si no lo hay, se redirige al usuario a la página
         * de logado.
         */

        /* Si hay un usuario logado, se efectúa la acción determinada por el atributo
         * opción del ActionForm asociado.
         */
        ClientesActionForm af = (ClientesActionForm) form;
        String opcion = af.getOpcion().toLowerCase();
        String result = "failure";
        switch (opcion) {
            case "menu":
                result = "menu";
                break;
            case "grabar":
                crear(af, response.getWriter());
                break;
            case "buscar":
                result = buscar(af, response.getWriter());
                break;
            case "eliminar":
                result = eliminar(af, response.getWriter());
                break;
            case "modificar":
                result = modificar(af, response.getWriter());
                break;

        }
        return mapping.findForward(result);
    }

//<editor-fold defaultstate="collapsed" desc="private methods">
    private String buscar(ClientesActionForm form, PrintWriter out) {
        /* Basicamente, se efectúa una búsqueda de todos los clientes cuyos datos correspondan a los aportados por
         * el usuario en el formulario de búsqueda. Este resultado es asignado al atributo resultadoBusqueda del
         * ActionForm y después se recorre para construir una cadena JSON que se devolverá al cliente por medio
         * del objeto response.
         * Cualquier excepción también se devolverá de la misma forma.
         */
        String result = "failure";
        form.setResultadoBusqueda(ClienteDAO.search(form.getNombre(), form.getContacto(), form.getEmail(), form.getTelefono()));
        JSONArray jsonArray = new JSONArray();
        try {
            for (Cliente cli : form.getResultadoBusqueda()) {
                JSONObject json = new JSONObject();
                json.put("id", cli.getIdCliente());
                json.put("idDireccion", cli.getDireccion() != null ? cli.getDireccion().getIdDireccion() : "");
                json.put("direccion", cli.getDireccion() != null ? cli.getDireccion().getDomicilio() : "");
                json.put("poblacion", cli.getDireccion() != null ? cli.getDireccion().getPoblacion() : "");
                json.put("provincia", cli.getDireccion() != null ? cli.getDireccion().getProvincia() : "");
                json.put("cp", cli.getDireccion() != null ? cli.getDireccion().getCp() : "");
                json.put("nombre", cli.getNombre());
                json.put("contacto", cli.getContacto());
                json.put("email", cli.getEmail());
                json.put("telefono", cli.getTelefono());
                
                jsonArray.put(json);
            }
            out.print(jsonArray);
            result = "success";
        } catch (JSONException ex) {
            out.println("<div id='excepcion'>");
            out.println(String.format("<ul><li>Se ha producido el siguiente error: %s</li></ul>", ex.getMessage()));
            out.println("</div>");
        } finally {
            return result;
        }
    }

    private String crear(ClientesActionForm form, PrintWriter out) {
         /* Para crear un nuevo cliente primero se crea un objeto de la clase Dirección con todos
         * los atributos obtenidos del ActionForm. Este objeto se referencia desde el nuevo objeto
         * cliente, que finalmente se persiste por medio de la clase ClienteDAO.
         */
        String result = "failure";
        try {
            Direccion direccion = new Direccion(form.getDireccion(), form.getPoblacion(), form.getProvincia(), form.getCp());
            Cliente clie = new Cliente(direccion, form.getNombre(), form.getContacto(), form.getEmail(), form.getTelefono());

            ClienteDAO.save(clie);
            form.getMisClientes().add(clie);
            result = "success";
        } catch (HibernateException ex) {
             /* Solo se devuelve una cadena en el response si se ha producido alguna excepción */
            out.println("<div id='excepcion'>");
            out.println(String.format("<ul><li>Se ha producido el siguiente error: %s</li></ul>", ex.getMessage()));
            out.println("</div>");
        } finally {
            return result;
        }
    }

    private String eliminar(ClientesActionForm form, PrintWriter out) {
        String result = "failure";
        try {
            ClienteDAO.delete(form.getId());
            result = "success";
        } catch (HibernateException ex) {
            out.println("<div id='excepcion'>");
            out.println(String.format("<ul><li>Se ha producido el siguiente error: %s</li></ul>", ex.getCause()));
            out.println("</div>");
        } finally {
            return result;
        }
    }

    private String modificar(ClientesActionForm form, PrintWriter out) {
          /* Para modificar se procede de forma similar a la creación, con la salvedad de que ahora es necesario
         * asignar el cliente el id que tenemos en el atributo correspondiente del ActionForm. De otra manera, 
         * se tomaría al cliente por uno nuevo y se volvería a crear en la base de datos.
         */
        String result = "failure";
        try {
            Direccion direccion = new Direccion(form.getDireccion(), form.getPoblacion(), form.getProvincia(), form.getCp());
            direccion.setIdDireccion(form.getIdDireccion());
            Cliente clie = new Cliente(direccion, form.getNombre(), form.getContacto(), form.getEmail(), form.getTelefono());
            clie.setIdCliente(form.getId());
            ClienteDAO.save(clie);
            form.getMisClientes().add(clie);
            result = "success";
        } catch (HibernateException ex) {
            out.println("<div id='excepcion'>");
            out.println(String.format("<ul><li>Se ha producido el siguiente error: %s</li></ul>", ex.getMessage()));
            out.println("</div>");
        } finally {
            return result;
        }
    }
    //</editor-fold>
}
